<?php

namespace app\repository;


use app\enum\StatusConstant;
use app\popo\model\Dish;
use app\popo\model\DishFlavor;
use app\popo\model\Setmeal;
use app\popo\model\SetmealDish;
use app\popo\vo\DishVo;
use app\support\JwtHelper;
use app\support\ListContainer;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use support\Db;

class DishRepository
{

    public function listOf(array $dishPageQueryDTO): ListContainer
    {
        $categoryId = Arr::get($dishPageQueryDTO, "categoryId");
        $name = Arr::get($dishPageQueryDTO, "name");
        $status = Arr::get($dishPageQueryDTO, "status");
        $pageSize = Arr::get($dishPageQueryDTO, "pageSize", 20);

        $query = Dish::query()->with("category")
        ->when($categoryId, function (Builder $builder) use ($categoryId){
            $builder->where("category_id", $categoryId);
        })->when($status, function (Builder $builder) use ($status){
            $builder->where("status", $status);
        })->when($name, function (Builder $builder) use ($name){
            $name = "%$name%";
            $builder->where("name", "like", $name);
        })
        ->orderByDesc("create_time");

        return new ListContainer($query->paginate($pageSize), function (Dish $dish) {
            $category = $dish->category;
            $data = array_merge($dish->toArray(), array(
                "category_name" => Arr::get($category, "name")
            ));
            return DishVo::fromArray($data)->toArray();
        });
    }

    public function getDishById($id): array
    {
        $dishWithFlavors = Dish::query()
            ->with(array("flavors", "category"))
            ->find($id);

        if ($dishWithFlavors) {
            return [
                'categoryId' => $dishWithFlavors->category_id,
                'categoryName' => $dishWithFlavors->category->name,
                'description' => $dishWithFlavors->description,
                'flavors' => $dishWithFlavors->flavors->map(function (DishFlavor $flavor) {
                    return
                        [
                            'dishId' => $flavor->dish_id,
                            'id' => $flavor->id,
                            'name' => $flavor->name,
                            'value' => $flavor->value
                        ];
                }),
                'id' => $dishWithFlavors->id,
                'image' => $dishWithFlavors->image,
                'name' => $dishWithFlavors->name,
                'price' => $dishWithFlavors->price,
                'status' => $dishWithFlavors->status,
                'updateTime' => $dishWithFlavors->update_time->format("Y-m-d H:i:s")
            ];
        }

        return array();
    }

    public function saveWithFlavors(array $params): array
    {
        $dish = new Dish();
        $dish->category_id = Arr::get($params, "categoryId");
        $dish->name = Arr::get($params, "name");
        $dish->price = Arr::get($params, "price");
        $dish->image = Arr::get($params, "image");
        $dish->description = Arr::get($params, "description");
        $dish->status = Arr::get($params, "status", 1);
        $dish->create_user = JwtHelper::getEmployee()->id;
        $dish->update_user = JwtHelper::getEmployee()->id;
        $dish->save();

        $flavors = Arr::get($params, "flavors", []);
        foreach ($flavors as &$flavor) {
            $flavor['dish_id'] = $dish->id;
            unset($flavor['id']);
        }
        $dish->flavors()->createMany($flavors);

        return $this->getDishById($dish->id);
    }

    public function deleteDishsWithFlavors(array $ids): void
    {
        Dish::query()->whereIn("id", $ids)->delete();
        DishFlavor::query()->whereIn("dish_id", $ids)->delete();
    }

    public function startOrStop($status, $id): void
    {
        Dish::query()->find($id)->updateWith([
            "status" => $status
        ]);

        // 如果是停售，还要把相关套餐停售
        if ($status == StatusConstant::DISABLE) {
            $setmealIds = SetmealDish::where("dish_id", $id)
                ->pluck("setmeal_id");

            if ($setmealIds->isNotEmpty()) {
                Setmeal::query()
                    ->whereIn("id", $setmealIds)
                    ->update(["status" => StatusConstant::DISABLE]);
            }
        }
    }

    public function update(array $dishWithFlavors)
    {
        Db::transaction(function () use ($dishWithFlavors) {
            // 1. 更新 Dish
            $dishId = $dishWithFlavors["id"];

            Dish::query()->where("id", $dishId)->update([
                "name"        => $dishWithFlavors["name"] ?? null,
                "price"       => $dishWithFlavors["price"] ?? null,
                "image"       => $dishWithFlavors["image"] ?? null,
                "description" => $dishWithFlavors["description"] ?? null,
                "status"      => $dishWithFlavors["status"] ?? null,
                "category_id" => $dishWithFlavors["categoryId"] ?? null,
            ]);

            // 2. 删除旧的 DishFlavors
            DishFlavor::query()->where("dish_id", $dishId)->delete();

            // 3. 重新插入新的 DishFlavors
            if (!empty($dishWithFlavors["flavors"])) {
                $flavors = array_map(function ($flavor) use ($dishId) {
                    return [
                        "dish_id" => $dishId,
                        "name"    => $flavor["name"],
                        "value"   => $flavor["value"],
                    ];
                }, $dishWithFlavors["flavors"]);

                DishFlavor::insert($flavors);
            }
        });
    }

    public function list(array $params): array
    {
        $query = Dish::query();

        // name 模糊查询
        if ($name = Arr::get($params, "name")) {
            $query->where("name", "like", "%{$name}%");
        }

        // categoryId 精确查询
        if ($categoryId = Arr::get($params, "categoryId")) {
            $query->where("category_id", $categoryId);
        }

        // status 精确查询
        if (($status = Arr::get($params, "status")) !== null) {
            $query->where("status", $status);
        }

        // 排序
        $list = $query->orderBy("create_time", "desc")
            ->get([
                "id",
                "category_id",
                "name",
                "price",
                "image",
                "description",
                "status",
                "create_time",
                "create_user",
                "update_time",
                "update_user",
            ]);

        // 转成数组并改成驼峰命名
        return $list->map(function ($item) {
            return [
                "id"          => $item->id,
                "categoryId"  => $item->category_id,
                "name"        => $item->name,
                "price"       => $item->price,
                "image"       => $item->image ? get_full_url($item->image) : null,
                "description" => $item->description,
                "status"      => $item->status,
                "createTime"  => $item->create_time,
                "createUser"  => $item->create_user,
                "updateTime"  => $item->update_time,
                "updateUser"  => $item->update_user,
            ];
        })->toArray();
    }
}